import { Singleton } from '../Base/Singleton'

interface IItem {
  callbackFunc: Function
  ctx?: unknown
}

export default class EventManager extends Singleton {
  static get Instance() {
    return super.getInstance<EventManager>()
  }

  private eventMap: Map<string, IItem[]> = new Map()

  // 订阅事件
  on(eventName: string, callbackFunc: Function, ctx?: unknown) {
    if (this.eventMap.has(eventName)) {
      this.eventMap.get(eventName).push({ callbackFunc, ctx })
    } else {
      this.eventMap.set(eventName, [{ callbackFunc, ctx }])
    }
  }

  // 取消订阅事件
  off(eventName: string, callbackFunc: Function) {
    if (this.eventMap.has(eventName)) {
      const index = this.eventMap.get(eventName).findIndex(item => item.callbackFunc === callbackFunc)
      if (index > -1) {
        this.eventMap.get(eventName).splice(index, 1)
      }
    }
  }

  // 发布事件，触发订阅事件时绑定的回调函数
  emit(eventName: string, ...args: unknown[]) {
    if (this.eventMap.has(eventName)) {
      this.eventMap.get(eventName).forEach(({ callbackFunc, ctx }) => {
        ctx ? callbackFunc.apply(ctx, args) : callbackFunc(...args)
      })
    }
  }

  // 清空所有事件
  clear() {
    this.eventMap.clear()
  }
}
